package inabit.inabitcompiler.productions.rule;

import inabit.compiler.parser.grammar.NonTerminal;
import inabit.compiler.parser.grammar.Production;
import inabit.compiler.parser.grammar.Symbol;
import inabit.compiler.parser.grammar.Terminal;
import inabit.data.Rule;
import inabit.inabitcompiler.lexical.InabitTokenClass;
import inabit.inabitcompiler.parser.InabitSemanticAction;

/**R -> id : if E then E;*/
/**@author Rafael Rocha*/
public class R_Rule extends Production{
	private Terminal id;
	private NonTerminal E1;
	private NonTerminal E2;
	
	public R_Rule() {
		super("R");
	}
	
	public Symbol[] production(NonTerminal nonTerminal) {
		id = new Terminal(InabitTokenClass.ID);
		E1 = new NonTerminal("E");
		E2 = new NonTerminal("E");
		Symbol[] symbols = {
				id,
				new Terminal(InabitTokenClass.COLON),
				new Terminal(InabitTokenClass.IF),
				E1,
				new Terminal(InabitTokenClass.THEN),
				E2,
				new InabitSemanticAction(nonTerminal) {
					@Override
					public void execute() throws Exception {
						Rule rule = new Rule(id.getValue(), getExpression(E1.code), getExpression(E2.code));
						
						for(Rule r : getDeclaredRules()) {
							if(r.getID().equals(id.getValue())) {
								throw new Exception("Rule " + r.getID() + " was already declared before");
							}
						}
						addRule(rule);
					}
				},
				new Terminal(InabitTokenClass.SEMI_COLON)
				
		};
		return symbols;
	}
}
